package SpLib.Net
{
	import SpLib.Com.SingletonFactory;
	import org.dm.objSys.NetObjMgr;
	import SpLib.std.iterator;
	import SpLib.std.map;
	
	public class NetMsgMgr
	{
		private static var s_Instance:NetMsgMgr = null;
		private var m_szSocket:map;
		private var m_DefSocket:SpLib.Net.Socket = null;

		public function NetMsgMgr()
		{
			if(SpLib.Net.NetMsgMgr.s_Instance!=null)
			{
				throw new Error("NetMsgMgr is Singleton");
			}
			
			if(SingletonFactory.Get("SpLib.Net.NetMsgMgr")!=null)
			{
				throw new Error("NetMsgMgr is Singleton");
			}
			
			m_szSocket = new SpLib.std.map(GLID.compare);
		}
		
		public static function GetInstance():NetMsgMgr
		{
			var gname:String = "SpLib.Net.NetMsgMgr";
			if(s_Instance==null)
			{
				s_Instance = SingletonFactory.Get(gname) as SpLib.Net.NetMsgMgr;
				if(s_Instance==null)
				{			
					s_Instance = new SpLib.Net.NetMsgMgr();
					SingletonFactory.Reg(gname,s_Instance);
				}
			}	
			
			return s_Instance;
		}
		
		public static function Connect(ip:String,port:int):SpLib.Net.Socket
		{
			if(IsConnected())
			{
				return GetInstance().m_DefSocket;
			}
			
			var socket:SpLib.Net.Socket = GetInstance().m_DefSocket;
			if(socket==null)
			{
				socket = new SpLib.Net.Socket(false);
			}
			
			socket.Connect(ip,port);
			GetInstance().m_DefSocket = socket;
			
			return socket;
		}
		
		public static function IsConnected():Boolean
		{
			if(GetInstance().m_DefSocket==null)
			{
				return false;
			}
			
			return GetInstance().m_DefSocket.connected;
		}
		
		private function _AddSocket(glid:GLID,socket:SpLib.Net.Socket):Boolean
		{	
			if(!m_szSocket.insert(glid,socket))
			{
				return false;
			}
			
			return true;
		}
		
		private function _DelSocket(glid:GLID):void
		{
			if(m_DefSocket!=null && m_DefSocket.m_GLID==glid)
			{
				m_DefSocket = null;
			}
			
			m_szSocket.remove(glid);
		}
		
		public static function RecvMsg(msg:SpLib.Net.NetMsg):void
		{
			GetInstance()._RecvMsg(msg);
		}
		
		private function _RecvMsg(msg:SpLib.Net.NetMsg):void
		{
			if(msg.m_nMsgtype==NetMsg.TYPE_RPC_RESP ||
				msg.m_nMsgtype==NetMsg.TYPE_SERVERPUSH)
			{
				SpLib.Net.RPC.MsgRet(msg);
				return;
			}
			
			NetObjMgr.Msg(msg);
		}
		
		private function _Send(pak:NetPak):void
		{
			if(pak.m_Msg.m_GLID.IsEmpty())
			{
				m_DefSocket.Send(pak);
				return;
			}
			
			var iter:SpLib.std.iterator = m_szSocket.find(pak.m_Msg.m_GLID);
			if(iter!=null)
			{
				var socket:SpLib.Net.Socket = iter.m_Data as SpLib.Net.Socket;
				socket.Send(pak);
			}
		}
		
		public static function AddSocket(glid:GLID,socket:SpLib.Net.Socket):Boolean
		{
			return GetInstance()._AddSocket(glid,socket);
		}
		
		public static function DelSocket(glid:GLID):void
		{
			GetInstance()._DelSocket(glid);
		}
		
		public static function SendMsg(msg:NetMsg):void
		{
			var pak:NetPak = new NetPak();
			pak.m_Msg = msg;
			GetInstance()._Send(pak);
		}
	}
}